package com.zhoug.zmui3.marquee;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.animation.LinearInterpolator;

import com.zhoug.common3.utils.LogUtils;
import com.zhoug.zmui3.R;

/**
 * 水平跑马灯
 *  setText之前需要stop,之后start
 *
 * @Author 35574
 * @Date 2020/7/2
 * @Description
 */
public class ZMUIMarqueeHorizontalTextView extends androidx.appcompat.widget.AppCompatTextView {
    private static final String TAG = ">>>ZMUIMarqueeHorizontal";
    private static final boolean DEBUG = false;
    private volatile boolean started = false;
    private float startX;//文字开始坐标x
    private float y;//文字坐标y
    private int speed = 3;//速度
    private float totalLength;
    public static final int MODEL_STAR = 1;//左
    public static final int MODEL_CENTER = 2;//中
    public static final int MODEL_END = 3;//右
    /**
     * 起点x坐标位置
     */
    private int startModel = MODEL_STAR;
    private ValueAnimator animator;
    private float lastTextSize;//上次计算时的文字大小
    private String lastContent;//上次计算时的内容

    public ZMUIMarqueeHorizontalTextView(Context context) {
        this(context, null);
    }

    public ZMUIMarqueeHorizontalTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ZMUIMarqueeHorizontalTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setSingleLine(true);
        setGravity(Gravity.TOP | Gravity.START);
        setLines(1);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ZMUIMarqueeHorizontalTextView);
        startModel = typedArray.getInt(R.styleable.ZMUIMarqueeHorizontalTextView_zmui_startModel, MODEL_STAR);
        speed = typedArray.getInt(R.styleable.ZMUIMarqueeHorizontalTextView_zmui_speed, 3);
        typedArray.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
//        LogUtils.d(TAG, "onDraw:");
        CharSequence text = getText();
        if (text != null && text.length() > 0) {
            getPaint().setTextAlign(Paint.Align.LEFT);
            getPaint().setColor(getCurrentTextColor());
            if(y<=0){
                //计算垂直中心线
                Paint.FontMetrics fontMetrics = getPaint().getFontMetrics();
                y = (getMeasuredHeight() - fontMetrics.descent - fontMetrics.ascent) / 2;
            }
            canvas.drawText(text, 0, text.length(), startX, y, getPaint());
        } else {
            //没有文字调用父类方法
            super.onDraw(canvas);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (DEBUG) {
            LogUtils.d(TAG, "onMeasure:MeasuredWidth=" + getMeasuredWidth());
        }
        init();
    }

    private void init() {
        float textSize = getTextSize();
        String content=null;
        CharSequence text1 = getText();
        if(text1!=null){
            content=text1.toString();
        }
        if(textSize==lastTextSize && lastContent!=null && lastContent.equals(content)){
            return;
        }
        lastTextSize=textSize;
        lastContent=content;

        if (hasContent()) {
//        LogUtils.d(TAG, "onMeasure:y=" + y);
            CharSequence text = getText();
            totalLength = getPaint().measureText(text, 0, text.length());
//        LogUtils.d(TAG, "onMeasure:totalLength=" + totalLength);
            if (startModel == MODEL_STAR) {
                startX = 0;
            } else if (startModel == MODEL_END) {
                startX = getMeasuredWidth();
            } else if (startModel == MODEL_CENTER) {
                if (totalLength < getMeasuredWidth()) {
                    startX = (getMeasuredWidth() - totalLength) / 2;
                } else {
                    startX = getMeasuredWidth() >> 1;
                }
            }

        }

    }


    /**
     * 是否有内容
     * @return
     */
    private boolean hasContent(){
        CharSequence text = getText();
        if(text!=null && text.length()>0){
            return true;
        }
        return false;
    }

    /**
     * 开始滚动
     */
    public void start() {
        if(!hasContent()){
            if (DEBUG) {
                LogUtils.d(TAG, "start:还没有内容不能滚动");
            }
            return;
        }
        if (!started) {
            if (DEBUG) {
                LogUtils.d(TAG, "start:开始滚动speed=" + speed);
            }
            init();
            started = true;
            animator = ValueAnimator.ofFloat(0, 100);
            animator.setDuration(1000 * 60);
            //无限重复
            animator.setRepeatMode(ValueAnimator.RESTART);
            animator.setRepeatCount(-1);
            //均值变化
            animator.setInterpolator(new LinearInterpolator());
            //刷新
            animator.addUpdateListener(animation -> {
                //必须要文字长度大于0才刷新
                if (totalLength > 0) {
                    startX -= speed;
                    if (startX < -totalLength) {
                        startX = getMeasuredWidth();
                    }
                    postInvalidate();
                }

            });
            animator.start();
        }
    }

    /**
     * 停止滚动
     */
    public void stop() {
        if (animator != null) {
            animator.cancel();
            animator = null;
            if (DEBUG) {
                LogUtils.d(TAG, "stop: 停止滚动");
            }
        }
        started = false;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        stop();
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        // 第三步，重写computeScroll()方法，并在其内部完成平滑滚动的逻辑
//        LogUtils.d(TAG, "computeScroll:");
    }

    public boolean isStarted() {
        return started;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getStartModel() {
        return startModel;
    }

    public void setStartModel(int startModel) {
        this.startModel = startModel;
    }
}
